home *** CD-ROM | disk | FTP | other *** search
/ APDL Other Worlds / APDL Other Worlds Collection.iso / SF3000 / Extras / !SFtoSpr / c / SaveSprites < prev    next >
Encoding:
Text File  |  2003-11-06  |  11.9 KB  |  354 lines

  1. /*
  2.  *  SFtoSpr - Star Fighter 3000 graphics converter
  3.  *  Savebox for sprites extracted from MapTiles/Planets
  4.  *  Copyright (C) 2000  Chris Bazley
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public Licence as published by
  8.  *  the Free Software Foundation; either version 2 of the Licence, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public Licence for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public Licence
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /* ANSI library files */
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <stdbool.h>
  26.  
  27. /* RISC OS library files */
  28. #include "wimp.h"
  29. #include "toolbox.h"
  30. #include "event.h"
  31. #include "wimplib.h"
  32. #include "saveas.h"
  33. #include "window.h"
  34. #include "gadgets.h"
  35. #include "flex.h"
  36.  
  37. /* My library files */
  38. #include "err.h"
  39. #include "msgtrans.h"
  40. #include "hourglass.h"
  41. #include "Macros.h"
  42. #include "ViewsMenu.h"
  43. #include "Loader.h"
  44. #include "SFformats.h"
  45. #include "SprFormats.h"
  46. #include "NoBudge.h"
  47. #include "TboxBugs.h"
  48. #include "FilePerc.h"
  49.  
  50. /* Local headers */
  51. #include "Utils.h"
  52. #include "SFgfxconv.h"
  53. #include "Main.h"
  54. #include "SaveSprites.h"
  55.  
  56. /* Gadget IDs */
  57. #define TEXTOSPR_SAVEANIMS  0x00
  58.  
  59. typedef struct _SaveSpritesData
  60. {
  61.   ObjectId           saveas_id;
  62.   ObjectId           window_id;
  63.   char              *reset_file_name;
  64.   spriteareaheader  *sprite_area; /* flex block */
  65.   SF_MapTilesSetHdr *animations; /* copy of original tiles header */
  66.   int                reset_save_anims;
  67.   bool               no_budge;
  68. } SaveSpritesData;
  69.  
  70. /* -----------------------------------------------------------------------
  71.  *                       Function prototypes
  72.  */
  73.  
  74. static ToolboxEventHandler _SaveSprites_savehandler, _SaveSprites_ramhandler, _SaveSprites_savecompleted, _SaveSprites_deletedhandler, _SaveSprites_buttonshandler;
  75.  
  76. /* -----------------------------------------------------------------------
  77.  *                         Public functions
  78.  */
  79.  
  80. ObjectId SaveSprites_create(char *savepath, int data_saved, spriteareaheader **sprite_area, SF_MapTilesSetHdr **animations)
  81. {
  82.   /* If animations == NULL then we are saving planet graphics.
  83.      Must COPY animations to retain data (will be flex_free'd)
  84.      Must either RE-ANCHOR sprite_area or flex_free() it
  85.      (will only be flex_free'd if we return NULL_ObjectId) */
  86.   SaveSpritesData *newblk;
  87.   char *views_path, *list_tok, *obj_templ;
  88.  
  89.   /* Grab memory */
  90.   newblk = malloc(sizeof(SaveSpritesData));
  91.   if(newblk == NULL)
  92.     MG_RETV("NoMem", NULL_ObjectId) /* failure */
  93.  
  94.   newblk->no_budge = false; /* we aren't preventing flex budging */
  95.   newblk->reset_file_name = NULL;
  96.   newblk->animations = NULL;
  97.  
  98.   if(animations != NULL) {
  99.     /* Copy header of tiles set to preserve animations */
  100.     newblk->animations = malloc(sizeof(SF_MapTilesSetHdr));
  101.     if(newblk->animations == NULL) {
  102.       MG("NoMem");
  103.       goto errexit_free;
  104.     }
  105.     nobudge_register(256);
  106.     memcpy(newblk->animations, *animations, sizeof(SF_MapTilesSetHdr));
  107.     nobudge_deregister();
  108.  
  109.     list_tok = "TexSprList";
  110.     obj_templ = "TexToSpr";
  111.  
  112.   } else {
  113.     list_tok = "PlaSprList";
  114.     obj_templ = "PlaToSpr";
  115.   }
  116.  
  117.   /* Create object */
  118.   if(E(toolbox_create_object(0, obj_templ, &newblk->saveas_id)))
  119.     goto errexit_free;
  120.   if(E(saveas_get_window_id(0, newblk->saveas_id, &newblk->window_id)))
  121.     goto errexit_delete;
  122.  
  123.   /* Store default settings */
  124.   if((newblk->reset_file_name = copystring(savepath)) == NULL)
  125.     goto errexit_delete;
  126.   if(animations != NULL) {
  127.     if(E(optionbutton_get_state(0, newblk->window_id, TEXTOSPR_SAVEANIMS, &newblk->reset_save_anims)))
  128.       goto errexit_delete;
  129.   }
  130.  
  131.   /* Add entry to iconbar menu */
  132.   if(data_saved)
  133.     views_path = savepath; /* we have real filepath */
  134.   else
  135.     views_path = ""; /* dummy filepath */
  136.   if(E(ViewsMenu_add(newblk->saveas_id, msgs_lookup_sub1(list_tok, tail(savepath, 3)), views_path)))
  137.     goto errexit_delete;
  138.  
  139.   /* Set up window */
  140.   if(E(saveas_set_file_name(0, newblk->saveas_id, savepath))
  141.   || E(saveas_set_file_type(0, newblk->saveas_id, FILETYPE_SPRITE))
  142.   || E(saveas_set_file_size(0, newblk->saveas_id, flex_size((flex_ptr)sprite_area)-4)))
  143.     goto errexit_menuremove;
  144.  
  145.   /*
  146.      Note the ObjectDeleted handler is registered AFTER anything that could cause an error and therefore premature deletion!
  147.   */
  148.   if(E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_SaveToFile,  _SaveSprites_savehandler, newblk))
  149.   || E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_FillBuffer,  _SaveSprites_ramhandler, newblk))
  150.   || E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_SaveCompleted, _SaveSprites_savecompleted, newblk))
  151.   || E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_DialogueCompleted, delete_object_handler, newblk))
  152.   || E(event_register_toolbox_handler(newblk->window_id, ActionButton_Selected, _SaveSprites_buttonshandler, newblk))
  153.   || E(event_register_toolbox_handler(newblk->saveas_id, Toolbox_ObjectDeleted, _SaveSprites_deletedhandler, newblk)))
  154.     goto errexit_menuremove;
  155.  
  156.   flex_reanchor((flex_ptr)&newblk->sprite_area, (flex_ptr)sprite_area);
  157.   return newblk->saveas_id; /* success */
  158.  
  159.   errexit_menuremove:
  160.     RE(ViewsMenu_remove(newblk->saveas_id));
  161.   errexit_delete:
  162.     RE(toolbox_delete_object(0, newblk->saveas_id));
  163.   errexit_free:
  164.     free(newblk->reset_file_name);
  165.     free(newblk->animations);
  166.     free(newblk);
  167.     return NULL_ObjectId; /* failure */
  168. }
  169.  
  170. /* -----------------------------------------------------------------------
  171.  *                          Private functions
  172.  */
  173.  
  174. /*
  175.  * Toolbox event handlers
  176.  */
  177.  
  178. static int _SaveSprites_savehandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  179. {
  180.   SaveAsSaveToFileEvent *save_to_file_block = (SaveAsSaveToFileEvent *)event;
  181.   SaveSpritesData *blk = (SaveSpritesData *)handle;
  182.   unsigned int flags = 0;
  183.  
  184.   /* Save output spritefile (from Planets or MapTiles) */
  185.   {
  186.     _kernel_oserror *err = perc_operation(FILEPERC_OP_SAVE, save_to_file_block->filename, FILETYPE_SPRITE|(1u<<31), (flex_ptr)&blk->sprite_area);
  187.     if(err != NULL) {
  188.       err_report(err->errnum, msgs_lookup_sub1("SaveFail", err->errmess));
  189.       goto exit;
  190.     }
  191.   }
  192.  
  193.   if(blk->animations != NULL) {
  194.     /* Check whether we should save animations textfile too */
  195.     int save_anims;
  196.     if(E(optionbutton_get_state(0, blk->window_id, TEXTOSPR_SAVEANIMS, &save_anims)))
  197.       goto exit;
  198.  
  199.     if(save_anims) {
  200.       /* We can't transfer them direct to another app */
  201.       if(!ViewsMenu_strcmp_nc(save_to_file_block->filename, "<Wimp$Scrap>")) {
  202. #ifndef OLD_SCL_STUBS
  203.         char texfilename[strlen(save_to_file_block->filename) + 4 + 1];
  204. #else
  205.         char *texfilename = malloc(strlen(save_to_file_block->filename) + 4 + 1);
  206.         if(texfilename == NULL) {
  207.           MG("NoMem");
  208.           goto exit;
  209.         }
  210. #endif
  211.         sprintf(texfilename, "%s/ani", save_to_file_block->filename);
  212.         
  213.         _kernel_oserror *err = save_animsfile(texfilename, blk->animations);
  214. #ifdef OLD_SCL_STUBS
  215.         free(texfilename);
  216. #endif
  217.         if(err != NULL) {
  218.           err_report(err->errnum, msgs_lookup_sub1("SaveFail", err->errmess));
  219.           goto exit;
  220.         }
  221.       }
  222.     }
  223.   }
  224.   flags = 1; /* success */
  225.  
  226. exit:
  227.   saveas_file_save_completed(flags, id_block->self_id, save_to_file_block->filename);
  228.   return 1; /* claim event */
  229. }
  230.  
  231. /* ----------------------------------------------------------------------- */
  232.  
  233. static int _SaveSprites_ramhandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  234. {
  235.   SaveAsFillBufferEvent *fill_buffer_event = (SaveAsFillBufferEvent *)event;
  236.   SaveSpritesData *blk = (SaveSpritesData *)handle;
  237.  
  238.   if(blk->no_budge) {
  239.     blk->no_budge = false;
  240.     nobudge_deregister();
  241.   }
  242.  
  243.   /* sprite file is sprite area without first word */
  244.   int spritefile_size = flex_size((flex_ptr)&blk->sprite_area) - 4;
  245.  
  246.   int chunk_size;
  247.   if(fill_buffer_event->no_bytes > spritefile_size)
  248.     /* Already sent all data */
  249.     chunk_size = 0;
  250.   else {
  251.     /* Calculate bytes still to send */
  252.     int bytes_to_go = spritefile_size - fill_buffer_event->no_bytes;
  253.     if(bytes_to_go > fill_buffer_event->size)
  254.       /* Can't fit remaining, so just fill buffer */
  255.       chunk_size = fill_buffer_event->size;
  256.     else
  257.       /* Send all of remaining data */
  258.       chunk_size = bytes_to_go;
  259.   }
  260.   nobudge_register(1024);
  261.   blk->no_budge = true;
  262.   RE(saveas_buffer_filled(0, id_block->self_id, (void *)((int)blk->sprite_area + 4 + fill_buffer_event->no_bytes), chunk_size));
  263.  
  264.   return 1; /* claim event */
  265. }
  266.  
  267. /* ----------------------------------------------------------------------- */
  268.  
  269. static int _SaveSprites_savecompleted(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  270. {
  271.   /* Save completed */
  272.   SaveSpritesData *blk = (SaveSpritesData *)handle;
  273.   if(blk->no_budge) {
  274.     blk->no_budge = false;
  275.     nobudge_deregister();
  276.   }
  277.   return 1; /* claim event */
  278. }
  279.  
  280. /* ----------------------------------------------------------------------- */
  281.  
  282. static int _SaveSprites_buttonshandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  283. {
  284.   ActionButtonSelectedEvent *abse = (ActionButtonSelectedEvent *)event;
  285.   SaveSpritesData *blk = (SaveSpritesData *)handle;
  286.  
  287.   if(!FLAG_SET(abse->hdr.flags, ActionButton_Selected_Adjust))
  288.     return 0; /* not interested */
  289.   
  290.   switch(id_block->self_component) {
  291.     case 0x82bc02: /* Cancel button */
  292.       /* Reset dbox state */
  293.       if(blk->reset_file_name != NULL)
  294.         RE(saveas_set_file_name(0, blk->saveas_id, blk->reset_file_name));
  295.     
  296.       if(blk->animations != NULL)
  297.         RE(optionbutton_set_state(0, id_block->self_id, TEXTOSPR_SAVEANIMS, blk->reset_save_anims));
  298.       break;
  299.       
  300. #ifndef SAVEAS_CRAP /* no point saving state if dbox closes anyway */
  301.     case 0x82bc03: /* Save button */
  302.       /* Record dbox state */
  303.       if(blk->animations != NULL)
  304.         RE(optionbutton_get_state(0, id_block->self_id, TEXTOSPR_SAVEANIMS, &blk->reset_save_anims));
  305.  
  306.       int len;
  307.       E_RETV(saveas_get_file_name(0, blk->saveas_id, NULL, 0, &len), 1)
  308.       free(blk->reset_file_name);
  309.       blk->reset_file_name = malloc(len+1);
  310.       if(blk->reset_file_name == NULL)
  311.         err_complain(255, msgs_global("NoMem"));
  312.       else
  313.         RE(saveas_get_file_name(0, blk->saveas_id, blk->reset_file_name, len, NU      break;
  314. #endif
  315.  
  316.     default:
  317.       return 0; /* unknown component */
  318.   }
  319.  
  320.   return 1; /* claim event */
  321. }
  322.  
  323. /* ----------------------------------------------------------------------- */
  324.  
  325. static int _SaveSprites_deletedhandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  326. {
  327.   SaveSpritesData *blk = (SaveSpritesData *)handle;
  328.  
  329.   if(blk->no_budge) {
  330.     nobudge_deregister();
  331.   }
  332.   /* deregister handlers */
  333.   RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_SaveToFile, _SaveSprites_savehandler, handle));
  334.   RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_FillBuffer,  _SaveSprites_ramhandler, handle));
  335.   RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_SaveCompleted, _SaveSprites_savecompleted, handle));
  336.   RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_DialogueCompleted, delete_object_handler, handle));
  337.   RE(event_deregister_toolbox_handler(blk->window_id, ActionButton_Selected, _SaveSprites_buttonshandler, handle));
  338.   RE(event_deregister_toolbox_handler(id_block->self_id, Toolbox_ObjectDeleted, _SaveSprites_deletedhandler, handle));
  339.  
  340.   /* Remove from iconbar menu */
  341.   RE(ViewsMenu_remove(id_block->self_id));
  342.  
  343.   /* free memory */
  344.   flex_free((flex_ptr)&blk->sprite_area);
  345.   free(blk->reset_file_name);
  346.   free(blk->animations);
  347.   free(blk);
  348.  
  349.   if(last_savebox == id_block->self_id)
  350.     last_savebox = NULL_ObjectId;
  351.  
  352.   return 1; /* claim event */
  353. }
  354.